using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using SolanumSolstice.Units;
using SolanumSolstice.Mapping;
 
namespace SolanumSolstice.Buildings
{
    public class Building
    {
        protected Texture2D texture;
        protected Texture2D emptyBar;
        protected Texture2D fullBar;
        protected Texture2D infested;
        protected Texture2D greenArrow;
        protected SpriteFont hudFont;
        protected SpriteFont smallFont;
        protected string name;
        protected Vector2 position;
        protected Vector2 entrance;
        protected int width;
        protected int height;
        protected bool isInfested;
        protected bool isSelected;
        protected float cleanseMultiplier;
        protected List<Unit> cleansers;
        protected List<Unit> zombies;
        protected int zombieCount;
        protected Random rand;
        protected BuildingType buildingType;
        protected ContentManager content;

        //Cleansing Reward stuff
        protected int researchGained;
        protected int foodGained;
        protected int woodGained;
        protected int civiliansGained;
        protected int scientistsGained;
        protected double cleanseTime;
        protected Color rewardColor;

        protected float infestedYOffset;
        protected float infestedYincrement;
       
        #region Accessors

        public float CleanseMultiplier { get { return cleanseMultiplier; } set { cleanseMultiplier = value; } }

        public Vector2 Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }

        public int Width
        {
            get
            {
                return width;
            }
            set
            {
                width = value;
            }
        }

        public int Height
        {
            get
            {
                return height;
            }
            set
            {
                height = value;
            }
        }

        public bool IsInfested
        {
            get
            {
                return isInfested;
            }
            set
            {
                isInfested = value;
            }
        }

        public bool IsSelected
        {
            get
            {
                return isSelected;
            }
            set
            {
                isSelected = value;
            }
        }

        public List<Unit> Cleansers
        {
            get
            {
                return cleansers;
            }
            set
            {
                cleansers = value;
            }
        }

        public List<Unit> Zombies
        {
            get
            {
                return zombies;
            }
            set
            {
                zombies = value;
            }
        }

        public Texture2D Texture
        {
            get
            {
                return texture;
            }

            set
            {
                texture = value;
            }
        }

        public Vector2 Entrance
        {
            get
            {
                return entrance;
            }
            set
            {
                entrance = value;
            }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public BuildingType BuildingType
        {
            get
            {
                return buildingType;
            }
            set
            {
                buildingType = value;
            }
        }

        
        #endregion


        public Building(ContentManager content, string name, Vector2 position, Vector2 entrance, int zombieCount)
        {
            this.position = position;
            this.entrance = entrance;
            if (zombieCount > 0) { isInfested = true; };
            isSelected = false;
            cleanseMultiplier = 1.0f;
            cleansers = new List<Unit>();
            zombies = new List<Unit>();
            this.zombieCount = zombieCount;
            rand = new Random();
            this.name = name;
            buildingType = BuildingType.None;
            this.content = content;
            infested = content.Load<Texture2D>("Content\\Txtr\\Sys\\infested");
            greenArrow = content.Load<Texture2D>("Content\\Txtr\\Sys\\greenarrow");
            infestedYOffset = 0;
            infestedYincrement = 1;

            for (int i = 0; i < zombieCount; i++)
            {
                ZombieCivilian zom = new ZombieCivilian(content, position);
                zom.InBuilding = true;
                
                zombies.Add(zom);
                
            }

            emptyBar = content.Load<Texture2D>("Content\\Txtr\\Units\\EmptyBar");
            fullBar = content.Load<Texture2D>("Content\\Txtr\\Units\\FullBarWhite");
            hudFont = content.Load<SpriteFont>("Content\\Fnt\\ArialSmall");
            smallFont = content.Load<SpriteFont>("Content\\Fnt\\ArialTiny");

            rewardColor = Color.Ivory;
        }

        public Building(ContentManager content, Texture2D texture, string name, Vector2 position, Vector2 entrance, int zombieCount)
            : this(content, name, position, entrance, zombieCount)
        {
            this.texture = texture;
            width = texture.Width;
            height = texture.Height;
        }

        public virtual void Update(GameTime gameTime, GamePadState gamePad, GameCursor gameCursor)
        {

            if (zombies.Count == 0)
            {
                isInfested = false;

                if (cleansers.Count > 0)
                {
                    cleanseTime = gameTime.TotalRealTime.TotalSeconds;
                    GiveCleansingReward();
                }

                foreach (Unit human in cleansers)
                {
                    human.InBuilding = false;
                }

                cleansers = new List<Unit>();
            }


            if (isInfested == true && cleansers.Count > 0)
            {
               
                foreach (Human milUnit in cleansers)
                {
                    /* DANIEL, fix this to accomodate the upgraded cleansing abilities */
                    if (milUnit.ActionReady && zombies.Count > 0)
                    {
                        int atkIndex = rand.Next(zombies.Count - 1);
                        milUnit.DealDamage(zombies[atkIndex], cleanseMultiplier);

                        if (zombies[atkIndex].IsDead)
                        {
                            zombies.Remove(zombies[atkIndex]);
                        }

                        milUnit.RecoveryTime = milUnit.Weapon.RecoveryTime;
                        milUnit.InitialRecoveryTime = milUnit.Weapon.RecoveryTime;

                        milUnit.ActionReady = false;
                    }


                }

                foreach (Zombie zombie in zombies)
                {
                    zombie.Update(gameTime, cleansers, zombies);

                    if (zombie.ActionReady && cleansers.Count > 0)
                    {
                        int atkIndex = rand.Next(cleansers.Count);
                        zombie.DealDamage(cleansers[atkIndex], 1);

                        if (cleansers[atkIndex].IsDead)
                        {
                            ExitBuilding(cleansers[atkIndex]);
                        }

                        zombie.RecoveryTime = 3;
                        zombie.InitialRecoveryTime = 3;

                        zombie.ActionReady = false;
                    }
                }

                
            }

            


        }

        public virtual void Draw(SpriteBatch spritebatch, int mapFocusX, int mapFocusY, GameTime gameTime)
        {
           

            if (isInfested == true)
            {
                spritebatch.Draw(texture, new Rectangle((int)position.X - mapFocusX, (int)position.Y - mapFocusY, width, height), Color.White);

                infestedYincrement += 4.5f;


                infestedYOffset = (float)Math.Sin(MathHelper.ToRadians(infestedYincrement)) * 4;


                 
                spritebatch.Draw(infested, new Rectangle((int)position.X - mapFocusX + (width / 2) - 25, (int)position.Y - mapFocusY + (int)infestedYOffset, 35, 35), Color.White);
                spritebatch.DrawString(smallFont, "" + zombies.Count, new Vector2((int)position.X - mapFocusX + (width / 2), (int)position.Y - mapFocusY + (int)infestedYOffset), Color.OrangeRed);

                if (isSelected == true)
                {
                    Color cleanseBar = Color.Green;

                    int cleanseBarLength = (int)(((float)zombies.Count / (float)zombieCount) * width);

                    if (zombies.Count < ((zombieCount * 2) / 3))
                    {
                        cleanseBar = Color.Yellow;
                    }

                    if (zombies.Count < (zombieCount / 3))
                    {
                        cleanseBar = Color.Red;
                    }


                    spritebatch.Draw(emptyBar, new Rectangle((int)position.X - mapFocusX, (int)position.Y - mapFocusY - 20, width, 15), Color.White);
                    spritebatch.Draw(fullBar, new Rectangle((int)position.X - mapFocusX, (int)position.Y - mapFocusY - 20, cleanseBarLength, 15), cleanseBar);

                    


                }
            }
            else
            {
                spritebatch.Draw(texture, new Rectangle((int)position.X - mapFocusX, (int)position.Y - mapFocusY, width, height),
                    new Rectangle(0, 0, width, height), Color.White);
            }

            if (buildingType == BuildingType.Beacon || buildingType == BuildingType.Supply || buildingType == BuildingType.Research)
            {
                infestedYincrement += 4.5f;


                infestedYOffset = (float)Math.Sin(MathHelper.ToRadians(infestedYincrement)) * 4;



                spritebatch.Draw(greenArrow, new Rectangle((int)position.X - mapFocusX + (width / 2) - 25, (int)position.Y - mapFocusY + (int)infestedYOffset, 35, 35), Color.White);

            }

            if(cleanseTime != 0 && rewardColor.A > 0)
            {
                if (gameTime.TotalRealTime.TotalSeconds > cleanseTime + 5.0d)
                {
                    rewardColor = new Color(rewardColor.ToVector4() - new Vector4(0, 0, 0, 0.01f));
                    
                }

                

                spritebatch.DrawString(smallFont, "Research +" + researchGained + "\n" +
                    "Food +" + foodGained + "\n" +
                    "Wood +" + woodGained + "\n" +
                    "Civilians +" + civiliansGained + "\n" +
                    "Researchers +" + scientistsGained + "\n", new Vector2((int)position.X - mapFocusX, (int)position.Y - mapFocusY - 30), rewardColor);

                



            }


            
        }

        public void GiveCleansingReward()
        {
            SolanumSolstice.soundBank.PlayCue("kaching");
            researchGained = zombieCount * 6;
            foodGained = rand.Next(zombieCount * 2);
            woodGained = rand.Next(zombieCount * 2);

            civiliansGained = rand.Next(6) - 4;

            if (civiliansGained < 0)
            {
                civiliansGained = 0;
            }
            scientistsGained = rand.Next(6) - 4;

            if (scientistsGained < 0)
            {
                scientistsGained = 0;
            }

            foreach (Building building in SolanumSolstice.buildings)
            {
                if (building.BuildingType == BuildingType.Research)
                {
                    ResearchBuilding rsh = (ResearchBuilding)building;
                    
                    rsh.TotalResearch += researchGained;

                    
                    
                    if (rsh.TotalResearch > rsh.ResearchNeeded)
                    {
                        rsh.TotalResearch = rsh.ResearchNeeded;
                    }
                }
            }

            SolanumSolstice.GetBase().Food += foodGained;
            SolanumSolstice.GetBase().Wood += woodGained;

            for (int i = 0; i < civiliansGained; i++)
            {
                SolanumSolstice.activeUnits.Add(new Civilian(content, this.entrance));
            }

            for (int i = 0; i < scientistsGained; i++)
            {
                SolanumSolstice.activeUnits.Add(new Researcher(content, this.entrance));
            }

        }


        public virtual void EnterBuilding(Human human)
        {
            if (isInfested && human.UnitClass == UnitClass.Military)
            {
                cleansers.Add(human);
                human.InBuilding = true;
            }
        }

        public virtual void ExitBuilding(Unit human)
        {
            if (human.UnitClass == UnitClass.Military)
            {
                Cop cop = (Cop)human;

                cop.InBuilding = false;
                cop.IsCleansing = false;
                cleansers.Remove(human);
            }
        }

        public virtual void DrawHUD(SpriteBatch spritebatch, Rectangle drawBoundary)
        {
            
        }





    }
}

